import SparkMD5 from "spark-md5";

/**
 * 读取一个文件的所有切片与最终hash
 */
export function getFileChunksAndHash(
  file: File
): Promise<{ chunkList: Blob[]; hash: string }> {
  console.time("computed");
  return new Promise((resolve, reject) => {
    // 切片集合
    const chunkList: Blob[] = [];
    // 切片大小
    const chunkSize = 1024 * 1024 * 5;
    // 切片数量
    const chunks = Math.ceil(file.size / chunkSize);
    // 当前切片下标
    let currentChunk = 0;
    // SparkMD5 实例
    const spark = new SparkMD5.ArrayBuffer();
    // fileReader 实例
    const fileReader = new FileReader();

    // 读取成功
    fileReader.onload = function () {
      // 读取到的内容
      const result = this.result as ArrayBuffer;
      // 将该 result 追加到 计算hash 的操作中
      spark.append(result);
      // currentChunk++
      currentChunk++;
      // 判断是否全部读取完成
      if (currentChunk < chunks) {
        // 计算下一个
        loadNext();
      } else {
        // 全部读取完成了，完成hash的计算
        const hash = spark.end();
        console.timeEnd("computed");
        // 让 Promise 完成
        resolve({
          chunkList,
          hash,
        });
      }
    };

    // 读取失败
    fileReader.onerror = function (error) {
      reject(error);
    };

    // 定义一个 loadNext 方法
    function loadNext() {
      // 开始字节
      const start = currentChunk * chunkSize;
      // 结束字节
      const end =
        start + chunkSize >= file.size ? file.size : start + chunkSize;
      // 切片
      const chunk = file.slice(start, end);
      // 将当前 chunk 追加到 chunkList 中
      chunkList.push(chunk);
      // 读取该切片的内容
      fileReader.readAsArrayBuffer(chunk);
    }

    // 默认调用一次 loadNext
    loadNext();
  });
}
